1   /*
2    * Copyright (C) 2007 The Guava Authors
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package com.google.common.collect;
18  
19  import static com.google.common.base.Preconditions.checkPositionIndex;
20  import static com.google.common.base.Preconditions.checkState;
21  import static com.google.common.collect.CollectPreconditions.checkRemove;
22  import static java.util.Collections.unmodifiableList;
23  
24  import com.google.common.annotations.GwtCompatible;
25  
26  import java.io.Serializable;
27  import java.util.AbstractSequentialList;
28  import java.util.Collection;
29  import java.util.ConcurrentModificationException;
30  import java.util.HashMap;
31  import java.util.Iterator;
32  import java.util.List;
33  import java.util.ListIterator;
34  import java.util.Map;
35  import java.util.Map.Entry;
36  import java.util.NoSuchElementException;
37  import java.util.Set;
38  
39  import javax.annotation.Nullable;
40  
41  /**
42   * An implementation of {@code ListMultimap} that supports deterministic
43   * iteration order for both keys and values. The iteration order is preserved
44   * across non-distinct key values. For example, for the following multimap
45   * definition: <pre>   {@code
46   *
47   *   Multimap<K, V> multimap = LinkedListMultimap.create();
48   *   multimap.put(key1, foo);
49   *   multimap.put(key2, bar);
50   *   multimap.put(key1, baz);}</pre>
51   *
52   * ... the iteration order for {@link #keys()} is {@code [key1, key2, key1]},
53   * and similarly for {@link #entries()}. Unlike {@link LinkedHashMultimap}, the
54   * iteration order is kept consistent between keys, entries and values. For
55   * example, calling: <pre>   {@code
56   *
57   *   map.remove(key1, foo);}</pre>
58   *
59   * <p>changes the entries iteration order to {@code [key2=bar, key1=baz]} and the
60   * key iteration order to {@code [key2, key1]}. The {@link #entries()} iterator
61   * returns mutable map entries, and {@link #replaceValues} attempts to preserve
62   * iteration order as much as possible.
63   *
64   * <p>The collections returned by {@link #keySet()} and {@link #asMap} iterate
65   * through the keys in the order they were first added to the multimap.
66   * Similarly, {@link #get}, {@link #removeAll}, and {@link #replaceValues}
67   * return collections that iterate through the values in the order they were
68   * added. The collections generated by {@link #entries()}, {@link #keys()}, and
69   * {@link #values} iterate across the key-value mappings in the order they were
70   * added to the multimap.
71   *
72   * <p>The {@link #values()} and {@link #entries()} methods both return a
73   * {@code List}, instead of the {@code Collection} specified by the {@link
74   * ListMultimap} interface.
75   *
76   * <p>The methods {@link #get}, {@link #keySet()}, {@link #keys()},
77   * {@link #values}, {@link #entries()}, and {@link #asMap} return collections
78   * that are views of the multimap. If the multimap is modified while an
79   * iteration over any of those collections is in progress, except through the
80   * iterator's methods, the results of the iteration are undefined.
81   *
82   * <p>Keys and values may be null. All optional multimap methods are supported,
83   * and all returned views are modifiable.
84   *
85   * <p>This class is not threadsafe when any concurrent operations update the
86   * multimap. Concurrent read operations will work correctly. To allow concurrent
87   * update operations, wrap your multimap with a call to {@link
88   * Multimaps#synchronizedListMultimap}.
89   *
90   * <p>See the Guava User Guide article on <a href=
91   * "http://code.google.com/p/guava-libraries/wiki/NewCollectionTypesExplained#Multimap">
92   * {@code Multimap}</a>.
93   *
94   * @author Mike Bostock
95   * @since 2.0 (imported from Google Collections Library)
96   */
97  @GwtCompatible(serializable = true, emulated = true)
98  public class LinkedListMultimap<K, V> extends AbstractMultimap<K, V>
99      implements ListMultimap<K, V>, Serializable {
100   /*
101    * Order is maintained using a linked list containing all key-value pairs. In
102    * addition, a series of disjoint linked lists of "siblings", each containing
103    * the values for a specific key, is used to implement {@link
104    * ValueForKeyIterator} in constant time.
105    */
106 
107   private static final class Node<K, V> extends AbstractMapEntry<K, V> {
108     final K key;
109     V value;
110     Node<K, V> next; // the next node (with any key)
111     Node<K, V> previous; // the previous node (with any key)
112     Node<K, V> nextSibling; // the next node with the same key
113     Node<K, V> previousSibling; // the previous node with the same key
114 
115     Node(@Nullable K key, @Nullable V value) {
116       this.key = key;
117       this.value = value;
118     }
119 
120     @Override
121     public K getKey() {
122       return key;
123     }
124 
125     @Override
126     public V getValue() {
127       return value;
128     }
129 
130     @Override
131     public V setValue(@Nullable V newValue) {
132       V result = value;
133       this.value = newValue;
134       return result;
135     }
136   }
137   
138   private static class KeyList<K, V> {
139     Node<K, V> head;
140     Node<K, V> tail;
141     int count;
142     
143     KeyList(Node<K, V> firstNode) {
144       this.head = firstNode;
145       this.tail = firstNode;
146       firstNode.previousSibling = null;
147       firstNode.nextSibling = null;
148       this.count = 1;
149     }
150   }
151 
152   private transient Node<K, V> head; // the head for all keys
153   private transient Node<K, V> tail; // the tail for all keys
154   private transient Map<K, KeyList<K, V>> keyToKeyList;
155   private transient int size;
156   
157   /*
158    * Tracks modifications to keyToKeyList so that addition or removal of keys invalidates
159    * preexisting iterators. This does *not* track simple additions and removals of values
160    * that are not the first to be added or last to be removed for their key.
161    */
162   private transient int modCount;
163 
164   /**
165    * Creates a new, empty {@code LinkedListMultimap} with the default initial
166    * capacity.
167    */
168   public static <K, V> LinkedListMultimap<K, V> create() {
169     return new LinkedListMultimap<K, V>();
170   }
171 
172   /**
173    * Constructs an empty {@code LinkedListMultimap} with enough capacity to hold
174    * the specified number of keys without rehashing.
175    *
176    * @param expectedKeys the expected number of distinct keys
177    * @throws IllegalArgumentException if {@code expectedKeys} is negative
178    */
179   public static <K, V> LinkedListMultimap<K, V> create(int expectedKeys) {
180     return new LinkedListMultimap<K, V>(expectedKeys);
181   }
182 
183   /**
184    * Constructs a {@code LinkedListMultimap} with the same mappings as the
185    * specified {@code Multimap}. The new multimap has the same
186    * {@link Multimap#entries()} iteration order as the input multimap.
187    *
188    * @param multimap the multimap whose contents are copied to this multimap
189    */
190   public static <K, V> LinkedListMultimap<K, V> create(
191       Multimap<? extends K, ? extends V> multimap) {
192     return new LinkedListMultimap<K, V>(multimap);
193   }
194 
195   LinkedListMultimap() {
196     keyToKeyList = Maps.newHashMap();
197   }
198 
199   private LinkedListMultimap(int expectedKeys) {
200     keyToKeyList = new HashMap<K, KeyList<K, V>>(expectedKeys);
201   }
202 
203   private LinkedListMultimap(Multimap<? extends K, ? extends V> multimap) {
204     this(multimap.keySet().size());
205     putAll(multimap);
206   }
207 
208   /**
209    * Adds a new node for the specified key-value pair before the specified
210    * {@code nextSibling} element, or at the end of the list if {@code
211    * nextSibling} is null. Note: if {@code nextSibling} is specified, it MUST be
212    * for an node for the same {@code key}!
213    */
214   private Node<K, V> addNode(
215       @Nullable K key, @Nullable V value, @Nullable Node<K, V> nextSibling) {
216     Node<K, V> node = new Node<K, V>(key, value);
217     if (head == null) { // empty list
218       head = tail = node;
219       keyToKeyList.put(key, new KeyList<K, V>(node));
220       modCount++;
221     } else if (nextSibling == null) { // non-empty list, add to tail
222       tail.next = node;
223       node.previous = tail;
224       tail = node;
225       KeyList<K, V> keyList = keyToKeyList.get(key);
226       if (keyList == null) {
227         keyToKeyList.put(key, keyList = new KeyList<K, V>(node));
228         modCount++;
229       } else {
230         keyList.count++;
231         Node<K, V> keyTail = keyList.tail;
232         keyTail.nextSibling = node;
233         node.previousSibling = keyTail;
234         keyList.tail = node;
235       }
236     } else { // non-empty list, insert before nextSibling
237       KeyList<K, V> keyList = keyToKeyList.get(key);
238       keyList.count++;
239       node.previous = nextSibling.previous;
240       node.previousSibling = nextSibling.previousSibling;
241       node.next = nextSibling;
242       node.nextSibling = nextSibling;
243       if (nextSibling.previousSibling == null) { // nextSibling was key head
244         keyToKeyList.get(key).head = node;
245       } else {
246         nextSibling.previousSibling.nextSibling = node;
247       }
248       if (nextSibling.previous == null) { // nextSibling was head
249         head = node;
250       } else {
251         nextSibling.previous.next = node;
252       }
253       nextSibling.previous = node;
254       nextSibling.previousSibling = node;
255     }
256     size++;
257     return node;
258   }
259 
260   /**
261    * Removes the specified node from the linked list. This method is only
262    * intended to be used from the {@code Iterator} classes. See also {@link
263    * LinkedListMultimap#removeAllNodes(Object)}.
264    */
265   private void removeNode(Node<K, V> node) {
266     if (node.previous != null) {
267       node.previous.next = node.next;
268     } else { // node was head
269       head = node.next;
270     }
271     if (node.next != null) {
272       node.next.previous = node.previous;
273     } else { // node was tail
274       tail = node.previous;
275     }
276     if (node.previousSibling == null && node.nextSibling == null) {
277       KeyList<K, V> keyList = keyToKeyList.remove(node.key);
278       keyList.count = 0;
279       modCount++;
280     } else {
281       KeyList<K, V> keyList = keyToKeyList.get(node.key);
282       keyList.count--;
283 
284       if (node.previousSibling == null) {
285         keyList.head = node.nextSibling;
286       } else {
287         node.previousSibling.nextSibling = node.nextSibling;
288       }
289       
290       if (node.nextSibling == null) {
291         keyList.tail = node.previousSibling;
292       } else {
293         node.nextSibling.previousSibling = node.previousSibling;
294       }
295     }
296     size--;
297   }
298 
299   /** Removes all nodes for the specified key. */
300   private void removeAllNodes(@Nullable Object key) {
301     Iterators.clear(new ValueForKeyIterator(key));
302   }
303 
304   /** Helper method for verifying that an iterator element is present. */
305   private static void checkElement(@Nullable Object node) {
306     if (node == null) {
307       throw new NoSuchElementException();
308     }
309   }
310 
311   /** An {@code Iterator} over all nodes. */
312   private class NodeIterator implements ListIterator<Entry<K, V>> {
313     int nextIndex;
314     Node<K, V> next;
315     Node<K, V> current;
316     Node<K, V> previous;
317     int expectedModCount = modCount;
318 
319     NodeIterator(int index) {
320       int size = size();
321       checkPositionIndex(index, size);
322       if (index >= (size / 2)) {
323         previous = tail;
324         nextIndex = size;
325         while (index++ < size) {
326           previous();
327         }
328       } else {
329         next = head;
330         while (index-- > 0) {
331           next();
332         }
333       }
334       current = null;
335     }
336     private void checkForConcurrentModification() {
337       if (modCount != expectedModCount) {
338         throw new ConcurrentModificationException();
339       }
340     }
341     @Override
342     public boolean hasNext() {
343       checkForConcurrentModification();
344       return next != null;
345     }
346     @Override
347     public Node<K, V> next() {
348       checkForConcurrentModification();
349       checkElement(next);
350       previous = current = next;
351       next = next.next;
352       nextIndex++;
353       return current;
354     }
355     @Override
356     public void remove() {
357       checkForConcurrentModification();
358       checkRemove(current != null);
359       if (current != next) { // after call to next()
360         previous = current.previous;
361         nextIndex--;
362       } else { // after call to previous()
363         next = current.next;
364       }
365       removeNode(current);
366       current = null;
367       expectedModCount = modCount;
368     }
369     @Override
370     public boolean hasPrevious() {
371       checkForConcurrentModification();
372       return previous != null;
373     }
374     @Override
375     public Node<K, V> previous() {
376       checkForConcurrentModification();
377       checkElement(previous);
378       next = current = previous;
379       previous = previous.previous;
380       nextIndex--;
381       return current;
382     }
383     @Override
384     public int nextIndex() {
385       return nextIndex;
386     }
387     @Override
388     public int previousIndex() {
389       return nextIndex - 1;
390     }
391     @Override
392     public void set(Entry<K, V> e) {
393       throw new UnsupportedOperationException();
394     }
395     @Override
396     public void add(Entry<K, V> e) {
397       throw new UnsupportedOperationException();
398     }
399     void setValue(V value) {
400       checkState(current != null);
401       current.value = value;
402     }
403   }
404 
405   /** An {@code Iterator} over distinct keys in key head order. */
406   private class DistinctKeyIterator implements Iterator<K> {
407     final Set<K> seenKeys = Sets.<K>newHashSetWithExpectedSize(keySet().size());
408     Node<K, V> next = head;
409     Node<K, V> current;
410     int expectedModCount = modCount;
411     
412     private void checkForConcurrentModification() {
413       if (modCount != expectedModCount) {
414         throw new ConcurrentModificationException();
415       }
416     }
417     @Override
418     public boolean hasNext() {
419       checkForConcurrentModification();
420       return next != null;
421     }
422     @Override
423     public K next() {
424       checkForConcurrentModification();
425       checkElement(next);
426       current = next;
427       seenKeys.add(current.key);
428       do { // skip ahead to next unseen key
429         next = next.next;
430       } while ((next != null) && !seenKeys.add(next.key));
431       return current.key;
432     }
433     @Override
434     public void remove() {
435       checkForConcurrentModification();
436       checkRemove(current != null);
437       removeAllNodes(current.key);
438       current = null;
439       expectedModCount = modCount;
440     }
441   }
442 
443   /** A {@code ListIterator} over values for a specified key. */
444   private class ValueForKeyIterator implements ListIterator<V> {
445     final Object key;
446     int nextIndex;
447     Node<K, V> next;
448     Node<K, V> current;
449     Node<K, V> previous;
450 
451     /** Constructs a new iterator over all values for the specified key. */
452     ValueForKeyIterator(@Nullable Object key) {
453       this.key = key;
454       KeyList<K, V> keyList = keyToKeyList.get(key);
455       next = (keyList == null) ? null : keyList.head;
456     }
457 
458     /**
459      * Constructs a new iterator over all values for the specified key starting
460      * at the specified index. This constructor is optimized so that it starts
461      * at either the head or the tail, depending on which is closer to the
462      * specified index. This allows adds to the tail to be done in constant
463      * time.
464      *
465      * @throws IndexOutOfBoundsException if index is invalid
466      */
467     public ValueForKeyIterator(@Nullable Object key, int index) {
468       KeyList<K, V> keyList = keyToKeyList.get(key);
469       int size = (keyList == null) ? 0 : keyList.count;
470       checkPositionIndex(index, size);
471       if (index >= (size / 2)) {
472         previous = (keyList == null) ? null : keyList.tail;
473         nextIndex = size;
474         while (index++ < size) {
475           previous();
476         }
477       } else {
478         next = (keyList == null) ? null : keyList.head;
479         while (index-- > 0) {
480           next();
481         }
482       }
483       this.key = key;
484       current = null;
485     }
486 
487     @Override
488     public boolean hasNext() {
489       return next != null;
490     }
491 
492     @Override
493     public V next() {
494       checkElement(next);
495       previous = current = next;
496       next = next.nextSibling;
497       nextIndex++;
498       return current.value;
499     }
500 
501     @Override
502     public boolean hasPrevious() {
503       return previous != null;
504     }
505 
506     @Override
507     public V previous() {
508       checkElement(previous);
509       next = current = previous;
510       previous = previous.previousSibling;
511       nextIndex--;
512       return current.value;
513     }
514 
515     @Override
516     public int nextIndex() {
517       return nextIndex;
518     }
519 
520     @Override
521     public int previousIndex() {
522       return nextIndex - 1;
523     }
524 
525     @Override
526     public void remove() {
527       checkRemove(current != null);
528       if (current != next) { // after call to next()
529         previous = current.previousSibling;
530         nextIndex--;
531       } else { // after call to previous()
532         next = current.nextSibling;
533       }
534       removeNode(current);
535       current = null;
536     }
537 
538     @Override
539     public void set(V value) {
540       checkState(current != null);
541       current.value = value;
542     }
543 
544     @Override
545     @SuppressWarnings("unchecked")
546     public void add(V value) {
547       previous = addNode((K) key, value, next);
548       nextIndex++;
549       current = null;
550     }
551   }
552 
553   // Query Operations
554 
555   @Override
556   public int size() {
557     return size;
558   }
559 
560   @Override
561   public boolean isEmpty() {
562     return head == null;
563   }
564 
565   @Override
566   public boolean containsKey(@Nullable Object key) {
567     return keyToKeyList.containsKey(key);
568   }
569 
570   @Override
571   public boolean containsValue(@Nullable Object value) {
572     return values().contains(value);
573   }
574 
575   // Modification Operations
576 
577   /**
578    * Stores a key-value pair in the multimap.
579    *
580    * @param key key to store in the multimap
581    * @param value value to store in the multimap
582    * @return {@code true} always
583    */
584   @Override
585   public boolean put(@Nullable K key, @Nullable V value) {
586     addNode(key, value, null);
587     return true;
588   }
589 
590   // Bulk Operations
591 
592   /**
593    * {@inheritDoc}
594    *
595    * <p>If any entries for the specified {@code key} already exist in the
596    * multimap, their values are changed in-place without affecting the iteration
597    * order.
598    *
599    * <p>The returned list is immutable and implements
600    * {@link java.util.RandomAccess}.
601    */
602   @Override
603   public List<V> replaceValues(@Nullable K key, Iterable<? extends V> values) {
604     List<V> oldValues = getCopy(key);
605     ListIterator<V> keyValues = new ValueForKeyIterator(key);
606     Iterator<? extends V> newValues = values.iterator();
607 
608     // Replace existing values, if any.
609     while (keyValues.hasNext() && newValues.hasNext()) {
610       keyValues.next();
611       keyValues.set(newValues.next());
612     }
613 
614     // Remove remaining old values, if any.
615     while (keyValues.hasNext()) {
616       keyValues.next();
617       keyValues.remove();
618     }
619 
620     // Add remaining new values, if any.
621     while (newValues.hasNext()) {
622       keyValues.add(newValues.next());
623     }
624 
625     return oldValues;
626   }
627 
628   private List<V> getCopy(@Nullable Object key) {
629     return unmodifiableList(Lists.newArrayList(new ValueForKeyIterator(key)));
630   }
631 
632   /**
633    * {@inheritDoc}
634    *
635    * <p>The returned list is immutable and implements
636    * {@link java.util.RandomAccess}.
637    */
638   @Override
639   public List<V> removeAll(@Nullable Object key) {
640     List<V> oldValues = getCopy(key);
641     removeAllNodes(key);
642     return oldValues;
643   }
644 
645   @Override
646   public void clear() {
647     head = null;
648     tail = null;
649     keyToKeyList.clear();
650     size = 0;
651     modCount++;
652   }
653 
654   // Views
655 
656   /**
657    * {@inheritDoc}
658    *
659    * <p>If the multimap is modified while an iteration over the list is in
660    * progress (except through the iterator's own {@code add}, {@code set} or
661    * {@code remove} operations) the results of the iteration are undefined.
662    *
663    * <p>The returned list is not serializable and does not have random access.
664    */
665   @Override
666   public List<V> get(final @Nullable K key) {
667     return new AbstractSequentialList<V>() {
668       @Override public int size() {
669         KeyList<K, V> keyList = keyToKeyList.get(key);
670         return (keyList == null) ? 0 : keyList.count;
671       }
672       @Override public ListIterator<V> listIterator(int index) {
673         return new ValueForKeyIterator(key, index);
674       }
675     };
676   }
677 
678   @Override
679   Set<K> createKeySet() {
680     return new Sets.ImprovedAbstractSet<K>() {
681       @Override public int size() {
682         return keyToKeyList.size();
683       }
684       @Override public Iterator<K> iterator() {
685         return new DistinctKeyIterator();
686       }
687       @Override public boolean contains(Object key) { // for performance
688         return containsKey(key);
689       }
690       @Override
691       public boolean remove(Object o) { // for performance
692         return !LinkedListMultimap.this.removeAll(o).isEmpty();
693       }
694     };
695   }
696 
697   /**
698    * {@inheritDoc}
699    *
700    * <p>The iterator generated by the returned collection traverses the values
701    * in the order they were added to the multimap. Because the values may have
702    * duplicates and follow the insertion ordering, this method returns a {@link
703    * List}, instead of the {@link Collection} specified in the {@link
704    * ListMultimap} interface.
705    */
706   @Override
707   public List<V> values() {
708     return (List<V>) super.values();
709   }
710 
711   @Override
712   List<V> createValues() {
713     return new AbstractSequentialList<V>() {
714       @Override public int size() {
715         return size;
716       }
717 
718       @Override public ListIterator<V> listIterator(int index) {
719         final NodeIterator nodeItr = new NodeIterator(index);
720         return new TransformedListIterator<Entry<K, V>, V>(nodeItr) {
721           @Override
722           V transform(Entry<K, V> entry) {
723             return entry.getValue();
724           }
725 
726           @Override
727           public void set(V value) {
728             nodeItr.setValue(value);
729           }
730         };
731       }
732     };
733   }
734 
735   /**
736    * {@inheritDoc}
737    *
738    * <p>The iterator generated by the returned collection traverses the entries
739    * in the order they were added to the multimap. Because the entries may have
740    * duplicates and follow the insertion ordering, this method returns a {@link
741    * List}, instead of the {@link Collection} specified in the {@link
742    * ListMultimap} interface.
743    *
744    * <p>An entry's {@link Entry#getKey} method always returns the same key,
745    * regardless of what happens subsequently. As long as the corresponding
746    * key-value mapping is not removed from the multimap, {@link Entry#getValue}
747    * returns the value from the multimap, which may change over time, and {@link
748    * Entry#setValue} modifies that value. Removing the mapping from the
749    * multimap does not alter the value returned by {@code getValue()}, though a
750    * subsequent {@code setValue()} call won't update the multimap but will lead
751    * to a revised value being returned by {@code getValue()}.
752    */
753   @Override
754   public List<Entry<K, V>> entries() {
755     return (List<Entry<K, V>>) super.entries();
756   }
757 
758   @Override
759   List<Entry<K, V>> createEntries() {
760     return new AbstractSequentialList<Entry<K, V>>() {
761       @Override public int size() {
762         return size;
763       }
764 
765       @Override public ListIterator<Entry<K, V>> listIterator(int index) {
766         return new NodeIterator(index);
767       }
768     };
769   }
770 
771   @Override
772   Iterator<Entry<K, V>> entryIterator() {
773     throw new AssertionError("should never be called");
774   }
775 
776   @Override
777   Map<K, Collection<V>> createAsMap() {
778     return new Multimaps.AsMap<K, V>(this);
779   }
780 }
781